package com.adhere.system.controller;

import com.adhere.system.pojo.RbacPrivilege;
import com.adhere.system.pojo.RbacRolePrivilege;
import com.adhere.system.pojo.vo.PageVo;
import com.adhere.system.service.IRbacPrivilegeService;
import com.adhere.system.service.IRbacRolePrivilegeService;
import com.adhere.system.utils.CodeUtils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * 权限管理
 */
@RestController
@RequestMapping("/privileges")
public class PrivilegeController {

    @Autowired
    private IRbacPrivilegeService privilegeService;

    @Autowired
    private IRbacRolePrivilegeService rolePrivilegeService;

    /**
     * 根据权限名称分页查询权限列表
     * @param currentPage 当前页,默认是1
     * @param pageSize 每页显示条数,默认是10
     * @param name 权限的名称
     * @return
     */
    @GetMapping("/")
    public PageVo<RbacPrivilege> getPrivilegeByPage (@RequestParam(required = false, defaultValue = "1") Integer currentPage,
                                                     @RequestParam(required = false, defaultValue = "10") Integer pageSize,
                                                     @RequestParam(required = false) String name) {

        return privilegeService.getPrivilegeByPage(currentPage, pageSize, name);

    }

    /**
     * 添加权限信息
     * @param privilege 权限信息对象
     */
    @PostMapping("/")
    public void addPrivilege (@RequestBody @Validated RbacPrivilege privilege) {
        QueryWrapper<RbacPrivilege> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("name", privilege.getName());
        RbacPrivilege privilegeRepeat = privilegeService.getOne(queryWrapper);
        if (privilegeRepeat != null) {
            throw new IllegalArgumentException("权限名称重复！");
        }
        QueryWrapper<RbacPrivilege> queryWrapper2 = new QueryWrapper<>();
        queryWrapper2.eq("scheme", privilege.getScheme());
        queryWrapper2.eq("uri", privilege.getUri());
        queryWrapper2.eq("request_method", privilege.getRequestMethod());
        RbacPrivilege privilegeRepeat2 = privilegeService.getOne(queryWrapper2);
        if (privilegeRepeat2 != null) {
            throw new IllegalArgumentException("相同协议,请求方式,uri组成的权限已经存在！");
        }
        boolean result = privilegeService.save(privilege);
        if (result) {
            privilege.setCode(CodeUtils.encode(privilege.getId()));
            privilegeService.updateById(privilege);
        }
    }

    /**
     * 根据code更新权限信息
     * @param privilege 权限信息对象
     */
    @PutMapping("/")
    public void updatePrivilege (@RequestBody @Validated RbacPrivilege privilege) {
        String code = privilege.getCode();
        Assert.notNull(code,"更新权限时,权限的code不能为空");
        QueryWrapper<RbacPrivilege> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("name", privilege.getName());
        queryWrapper.ne("code", code);
        RbacPrivilege privilegeRepeat = privilegeService.getOne(queryWrapper);
        if (privilegeRepeat != null) {
            throw new IllegalArgumentException("权限名称重复！");
        }
        QueryWrapper<RbacPrivilege> queryWrapper2 = new QueryWrapper<>();
        queryWrapper2.ne("code", code);
        queryWrapper2.eq("scheme", privilege.getScheme());
        queryWrapper2.eq("uri", privilege.getUri());
        queryWrapper2.eq("request_method", privilege.getRequestMethod());
        RbacPrivilege privilegeRepeat2 = privilegeService.getOne(queryWrapper2);
        if (privilegeRepeat2 != null) {
            throw new IllegalArgumentException("相同协议,请求方式,uri组成的权限已经存在！");
        }
        QueryWrapper<RbacPrivilege> updateWrapper = new QueryWrapper<>();
        updateWrapper.eq("code", code);
        privilegeService.update(privilege,updateWrapper);
    }

    /**
     * 根据 code 删除权限列表的信息
     * @param privilegeCode 权限Code
     */
    @DeleteMapping("/{privilegeCode}")
    public void deletePrivilege (@PathVariable String privilegeCode) {
        Assert.notNull(privilegeCode,"删除权限时,权限的code不能为空");
        List<RbacRolePrivilege> rbacRolePrivilegeList = rolePrivilegeService.selectByPrivilegeCode(privilegeCode);
        if (!ObjectUtils.isEmpty(rbacRolePrivilegeList)) {
            throw new IllegalArgumentException("此权限在被角色使用中，请先解除绑定关系！");
        }
        QueryWrapper<RbacPrivilege> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("code", privilegeCode);
        privilegeService.remove(queryWrapper);
    }


    /**
     * 根据角色 code 查询权限列表信息
     * @param roleCode 角色code
     * @return List<RbacPrivilege> 权限信息的列表
     */
    @GetMapping("/role/{roleCode}")
    public List<RbacPrivilege> getPrivilegeListByRoleCode (@PathVariable String roleCode) {
        return privilegeService.getPrivilegeListByRoleCode(roleCode);
    }

    /**
     * 根据 请求方式，协议，uri去查询权限的code
     * @param requestMethod 请求方式
     * @param scheme 协议
     * @param uri uri
     * @return 权限的code
     */
    @GetMapping("/code")
    public String getPrivilege (String requestMethod, String scheme, String uri) {
        return privilegeService.getPrivilege(requestMethod, scheme, uri);
    }

    /**
     * 根据权限code查询权限信息  编辑页面回显使用或者查看页面使用
     * @param privilegeCode 权限code
     * @return RbacPrivilege 权限实体对象
     */
    @GetMapping("/{privilegeCode}")
    public RbacPrivilege getPrivilegeByCode (@PathVariable String privilegeCode) {
        QueryWrapper<RbacPrivilege> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("code", privilegeCode);
        return privilegeService.getOne(queryWrapper);
    }

    /**
     * 根据权限名称查询权限列表
     * @param privilegeName 权限名称
     * @return List<RbacPrivilege> 权限列表信息
     */
    @GetMapping("/list")
    public List<RbacPrivilege> getPrivilegeListByName (@RequestParam(required = false) String privilegeName) {
        QueryWrapper<RbacPrivilege> queryWrapper = new QueryWrapper<>();
        if (StringUtils.hasText(privilegeName)) {
            queryWrapper.like("name", privilegeName);
        }
        return privilegeService.list(queryWrapper);
    }

}
